﻿using System;
using GeoAPI.Geometries;

namespace YJKGridTopologyCal.Algorithm
{
	public class NonRobustLineIntersector : LineIntersector
	{
		public static bool IsSameSignAndNonZero(double a, double b)
		{
			return a != 0.0 && b != 0.0 && ((a < 0.0 && b < 0.0) || (a > 0.0 && b > 0.0));
		}

		public override void ComputeIntersection(Coordinate p, Coordinate p1, Coordinate p2)
		{
			base.IsProper = false;
			double num = p2.Y - p1.Y;
			double num2 = p1.X - p2.X;
			double num3 = p2.X * p1.Y - p1.X * p2.Y;
			if (num * p.X + num2 * p.Y + num3 != 0.0)
			{
				this.Result = LineIntersector.NoIntersection;
				return;
			}
			double num4 = NonRobustLineIntersector.RParameter(p1, p2, p);
			if (num4 < 0.0 || num4 > 1.0)
			{
				this.Result = LineIntersector.NoIntersection;
				return;
			}
			base.IsProper = true;
			if (p.Equals(p1) || p.Equals(p2))
			{
				base.IsProper = false;
			}
			this.Result = LineIntersector.PointIntersection;
		}

		public override int ComputeIntersect(Coordinate p1, Coordinate p2, Coordinate p3, Coordinate p4)
		{
			base.IsProper = false;
			double num = p2.Y - p1.Y;
			double num2 = p1.X - p2.X;
			double num3 = p2.X * p1.Y - p1.X * p2.Y;
			double num4 = num * p3.X + num2 * p3.Y + num3;
			double num5 = num * p4.X + num2 * p4.Y + num3;
			if (num4 != 0.0 && num5 != 0.0 && NonRobustLineIntersector.IsSameSignAndNonZero(num4, num5))
			{
				return LineIntersector.NoIntersection;
			}
			double num6 = p4.Y - p3.Y;
			double num7 = p3.X - p4.X;
			double num8 = p4.X * p3.Y - p3.X * p4.Y;
			double num9 = num6 * p1.X + num7 * p1.Y + num8;
			double num10 = num6 * p2.X + num7 * p2.Y + num8;
			if (num9 != 0.0 && num10 != 0.0 && NonRobustLineIntersector.IsSameSignAndNonZero(num9, num10))
			{
				return LineIntersector.NoIntersection;
			}
			double num11 = num * num7 - num6 * num2;
			if (num11 == 0.0)
			{
				return this.ComputeCollinearIntersection(p1, p2, p3, p4);
			}
			double num12 = num2 * num8 - num7 * num3;
			base.Pa.X = num12 / num11;
			double num13 = num6 * num3 - num * num8;
			base.Pa.Y = num13 / num11;
			base.IsProper = true;
			if (base.Pa.Equals(p1) || base.Pa.Equals(p2) || base.Pa.Equals(p3) || base.Pa.Equals(p4))
			{
				base.IsProper = false;
			}
			if (base.PrecisionModel != null)
			{
				base.PrecisionModel.MakePrecise(base.Pa);
			}
			return LineIntersector.PointIntersection;
		}

		private int ComputeCollinearIntersection(Coordinate p1, Coordinate p2, Coordinate p3, Coordinate p4)
		{
			double num = 0.0;
			double num2 = 1.0;
			double num3 = NonRobustLineIntersector.RParameter(p1, p2, p3);
			double num4 = NonRobustLineIntersector.RParameter(p1, p2, p4);
			Coordinate coordinate;
			double num5;
			Coordinate coordinate2;
			double num6;
			if (num3 < num4)
			{
				coordinate = p3;
				num5 = num3;
				coordinate2 = p4;
				num6 = num4;
			}
			else
			{
				coordinate = p4;
				num5 = num4;
				coordinate2 = p3;
				num6 = num3;
			}
			if (num5 > num2 || num6 < num)
			{
				return LineIntersector.NoIntersection;
			}
			if (coordinate2 == p1)
			{
				base.Pa.CoordinateValue = p1;
				return LineIntersector.PointIntersection;
			}
			if (coordinate == p2)
			{
				base.Pa.CoordinateValue = p2;
				return LineIntersector.PointIntersection;
			}
			base.Pa.CoordinateValue = p1;
			if (num5 > num)
			{
				base.Pa.CoordinateValue = coordinate;
			}
			base.Pb.CoordinateValue = p2;
			if (num6 < num2)
			{
				base.Pb.CoordinateValue = coordinate2;
			}
			return LineIntersector.CollinearIntersection;
		}

		private static double RParameter(Coordinate p1, Coordinate p2, Coordinate p)
		{
			double num = Math.Abs(p2.X - p1.X);
			double num2 = Math.Abs(p2.Y - p1.Y);
			double result;
			if (num > num2)
			{
				result = (p.X - p1.X) / (p2.X - p1.X);
			}
			else
			{
				result = (p.Y - p1.Y) / (p2.Y - p1.Y);
			}
			return result;
		}
	}
}
